import router from '@/router'
import store from '@/store'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { asyncRoutes } from '@/router'

const whiteList = ['/login', '/404']

router.beforeEach(async(to, from, next) => {
  // 开启进度条
  NProgress.start()
  // !#1 如果有 token
  if (store.getters.token) {
    // 访问的是登录页，直接跳转到首页
    if (to.path === '/login') {
      // !如果说是用 next(路径) 跳转到的其他页面，是不会走 afterEach 的
      next('/')
      // NProgress.done()
    } else {
      // 否则放行
      // !在这儿获取用户信息才是最合适的，可以获取用户信息之后在放行进入到内页
      // 好处是：第一进去内页后直接就确定了用户身份，第二不会闪一下
      // if (!store.state.user.userInfo.userId) {
      if (!store.getters.userId) {
        // menus => 路由级别的权限标识
        const { roles: { menus }} = await store.dispatch('user/getUserInfo')
        // 用这个标识从一个完整的动态路由中进行筛选，筛选出和标识对应上的
        // 添加动态路由
        // !输入 /department，页面不刷新，会直接匹配这个路由，能命中直接展示，名不中才会走 404
        // !页面一旦刷新，第一次的时候路由规则都会从头到位匹配一遍
        // 循环 asyncRoutes 数组，看一些哪一项的 children 的第 1 项的 name 在不在 menus 中，在就保留这个对象
        const filterRoutes = asyncRoutes.filter(item => menus.includes(item.children[0].name))
        store.commit('user/setRoutes', filterRoutes)
        router.addRoutes([
          ...filterRoutes,
          { path: '*', redirect: '/404', hidden: true }
        ])
        // addRoutes 添加路由的操作是"异步"的，要想马上产生作用必须重新执行一下 beforeEach 的逻辑
        // next 参数中如果有路径，它会先把之前的路由中断掉，接下来重新执行 beforeEach 跳转到对应的路径
        // 假如 next() 放行的 /login 页，是直接放行
        // 假如 next(/login)，它会先中断之前的路由，接下来重新走 beforeEach，然后 /login
        // next(to.path)
        // 返回的时候要点两次
        // next(to)
        next({
          ...to,
          replace: true
        })
        return
      }
      next()
    }
  } else {
    // !#2 没有 token
    // 看一下访问的页面在不在白名单
    if (whiteList.includes(to.path)) {
      // 如果在，放行
      next()
    } else {
      // 否则拦截到登录页
      next('/login')
      // NProgress.done()
    }
  }
  NProgress.done()
})

router.afterEach(() => {
  NProgress.done()
})
